#ifndef BASE_MYSQL_H_
#define BASE_MYSQL_H_

#include "ctSingleton.h"
#include "ctTime.h"
#include "Zebra.h"
#include "mysqlpp/mysql++.h"
#include "mysqlpp/ssqls.h"
#include <mysql.h>

#define MYSQLPP_MYSQL_HEADERS_BURIED

class ctMYSQL {
        public:
                typedef mysqlpp::Connection             Connection ;
                typedef mysqlpp::Query		        Query;
                typedef mysqlpp::StoreQueryResult       StoreQueryResult;

        public:
                bool init(std::string db, std::string user, std::string host, std::string passwd) {
                        database_ = db;
                        host_ = host;
                        user_ = user;
                        password_ = passwd;

                        life_time_.now();

                        conn_ = new mysqlpp::Connection(false);
                        conn_->set_option(new mysqlpp::SetCharsetNameOption("utf8"));
                        conn_->set_option(new mysqlpp::MultiStatementsOption(CLIENT_MULTI_STATEMENTS));
                        if (conn_->connect(database_.c_str(), host_.c_str(), user_.c_str(), password_.c_str())) {
                                Zebra::logger->trace("%s: connect db(%s) ok", __PRETTY_FUNCTION__, db.c_str());
                                conn_->set_option(new mysqlpp::ReconnectOption(true));
                                return true;
                        }
                        else {
                                Zebra::logger->error("%s: connect db(%s) error(%s)", __PRETTY_FUNCTION__, database_.c_str(), conn_->error());
                                return false;
                        }
                }
                bool reconnectDB() {
                        Zebra::logger->warn(__PRETTY_FUNCTION__);
                        conn_->disconnect();
                        conn_->set_option(new mysqlpp::SetCharsetNameOption("utf8"));
                        conn_->set_option(new mysqlpp::MultiStatementsOption(CLIENT_MULTI_STATEMENTS));
                        if (conn_->connect(database_.c_str(), host_.c_str(), user_.c_str(), password_.c_str())) {
                                conn_->set_option(new mysqlpp::ReconnectOption(true));
                                life_time_.now();
                                Zebra::logger->trace("%s: connect db(%s) ok", __PRETTY_FUNCTION__, database_.c_str());
                                return true;
                        }
                        else {
                                Zebra::logger->error("%s: connect db(%s) error(%s)", __PRETTY_FUNCTION__, database_.c_str(), conn_->error());
                                return false;
                        }
                }
                std::string const getDB() {
                        return database_;
                }
                std::string const getHost() {
                        return host_;
                }
                std::string const getUser() {
                        return user_;
                }
                std::string const getPassword() {
                        return password_;
                }
                Connection * getConn() {
                        if(life_time_.elapse()>600) {
                                Zebra::logger->trace("mysql connection will be reconnected..");
                                reconnectDB();
                        }

                        ctMYSQL::Query query = conn_->query();

                        for (int i = 1; query.more_results(); ++i)
                        {
                                query.store_next();
                        }
                        /*conn_->set_option()
                        conn_.set_option(new mysqlpp::MultiStatementsOption(CLIENT_MULTI_STATEMENTS));*/
                        return conn_;
                }
                ctMYSQL() {
                        conn_ = NULL;
                }
                ~ctMYSQL() {
                        delete conn_;
                        conn_ = NULL;
                }
        private:
                std::string database_;
                std::string host_;
                std::string user_;
                std::string password_;
                mysqlpp::Connection *conn_;

                ctTime life_time_;
};

#endif //BASE_MYSQL_H_
